package io.gitee.dtdage.app.boot.starter.web.common;

import io.gitee.dtdage.app.boot.starter.web.common.handler.ControllerResultHandler;
import io.gitee.dtdage.app.boot.starter.web.common.handler.ExceptionHandlerFactory;
import io.gitee.dtdage.app.boot.starter.web.common.handler.InterceptorHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author WFT
 * @since 2024/4/14
 */
@Configuration
@ComponentScan
public class WebsiteAutoConfiguration {

    private class WebsiteConfigurerAdapter implements WebMvcConfigurer, ApplicationContextAware {

        private ApplicationContext context;

        @Override
        public void setApplicationContext(ApplicationContext context) {
            this.context = context;
        }

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //  绑定所有拦截器处理器
            this.context.getBeansOfType(InterceptorHandler.class)
                    .values()
                    .forEach(handler -> registry.addInterceptor(handler).addPathPatterns(handler.getPathPatterns()));
        }

        @Override
        public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
            //  绑定异常工厂处理器
            resolvers.add(0, this.context.getBean(ExceptionHandlerFactory.class));
        }

    }

    private class ReturnConfigurerAdapter implements ApplicationContextAware {
        @Override
        public void setApplicationContext(ApplicationContext context) {
            //  获取请求映射处理器对象
            RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
            //  配置接口返回值类型处理器
            List<HandlerMethodReturnValueHandler> list = new ArrayList<>();
            list.add(new ControllerResultHandler());
            //  复制已有的处理器
            Optional.ofNullable(adapter.getReturnValueHandlers()).ifPresent(list::addAll);
            adapter.setReturnValueHandlers(list);
        }
    }


    @Bean
    public WebsiteConfigurerAdapter websiteConfigurerAdapter() {
        return new WebsiteConfigurerAdapter();
    }

    @Bean
    public ReturnConfigurerAdapter returnConfigurerAdapter() {
        return new ReturnConfigurerAdapter();
    }

}